﻿using System;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace RoiControllers
{
    public class URCircle : ShapeBase
    {
        #region 字段|属性

        private RectangleF rectBound;   // 圆的最小外接矩形
        private float innerRadius;      // 内圆半径

        /// <summary> 圆形的矩形边界  </summary>
        [Description("圆的最小外接矩形区域")]
        public RectangleF RectFBound { get => rectBound; set => rectBound = value;}
        [Description("圆心坐标X")]
        public float X { get => rectBound.X; set => rectBound.X = value; }
        [Description("圆心坐标Y")]
        public float Y { get => rectBound.Y; set => rectBound.Y = value; }
        [Description("圆心坐标")]
        public PointF Center
        {
            get => new PointF(rectBound.X + rectBound.Width / 2,rectBound.Y + rectBound.Height / 2);
            set => rectBound.Location = value;
        }
        [Description("圆形外轮廓半径")]
        public float Radius => Math.Min(RectFBound.Width, RectFBound.Height) / 2;
        [Description("圆形内轮廓半径")]
        public float InnerRadius
        {
            get => innerRadius;
            set => innerRadius = Math.Min(Math.Max(0, Radius), Math.Max(0, value));
        }
        #endregion

        #region 构造函数
        public URCircle() : base()
        {
            Type = ShapeType.Circle;
            RectFBound = new RectangleF(0, 0, 100, 100); // 默认大小
            InnerRadius = 0; // 默认内部半径
        }
        public URCircle(PointF center, float radius) : base()
        {
            Type = ShapeType.Circle;
            RectFBound = new RectangleF(center.X - radius, center.Y - radius, radius * 2, radius * 2);
            InnerRadius = 0; // 默认内部半径
        }
        #endregion
        private void DrawHandles(Graphics graphics)
        {
            // 1、右侧外轮廓手柄
            DrawHandle(graphics, (Center.X + Radius), Center.Y);
            // 2、内部圆手柄
            DrawHandle(graphics, (Center.X + InnerRadius), Center.Y);
        }
        private void DrawRegionCenter(Graphics graphics)
        {
            // 1、计算矩形中心坐标
            int centerX = (int)(RectFBound.X + RectFBound.Width / 2);
            int centerY = (int)(RectFBound.Y + RectFBound.Height / 2);
            // 2、线长度大小（根据矩形大小自适应）
            int lineHalfLength = 3;
            // 3、绘制箭头
            using (Pen arrowPen = new Pen(BackColor, BorderWidth))
            {
                // 3.1 水平线
                Point left = new Point(centerX - lineHalfLength, centerY);
                Point right = new Point(centerX + lineHalfLength, centerY);
                graphics.DrawLine(arrowPen, left, right);
                // 3.2 垂直线
                Point top = new Point(centerX, centerY - lineHalfLength);
                Point bottom = new Point(centerX, centerY + lineHalfLength);
                graphics.DrawLine(arrowPen, top, bottom);
            }
        }
        private void DrawDescription(Graphics graphics)
        {
            using (SolidBrush brush = new SolidBrush(Color.LightGreen))
            {
                Font descriptionFont = new Font("Arial", 9);
                SizeF maxTextSize = graphics.MeasureString(Description, descriptionFont);
                float x = X + rectBound.Width / 2 - maxTextSize.Width / 2;
                float y = Y + rectBound.Height / 2 - maxTextSize.Height;
                graphics.DrawString(Description, descriptionFont, brush, x, y);
            }
        }
        #region 绘制形状相关方法
        public override void Move(PointF point)
        {
            int dx = (int)(point.X - LastLocation.X);
            int dy = (int)(point.Y - LastLocation.Y);
            X += dx;
            Y += dy;
            LastLocation = point;
            ExceteMoveCallback(this);
        }
        public override void Rotate(PointF point)
        {
        }
        public override void Resize(PointF point)
        {
            RectangleF rect = new RectangleF();
            switch (HandleType)
            {
                // 右侧手柄:调整外部大小
                case ShapeHandleType.Right:
                    float newRadius = Math.Abs(point.X - Center.X);
                    // 限制最小半径
                    if (newRadius < 10) newRadius = 10;
                    // 调整外部半径时保持内部半径的相对大小
                    rect = new RectangleF(
                        Center.X - newRadius,
                        Center.Y - newRadius,
                        newRadius * 2,
                        newRadius * 2);
                    break;
                // 内部手柄:调整内部半径
                case ShapeHandleType.Inner:
                    float newInnerRadius = (float)Math.Sqrt(
                    Math.Pow(point.X - Center.X, 2) +
                    Math.Pow(point.Y - Center.Y, 2));
                    // 限制内部半径最小为0，最大为外部半径-3
                    InnerRadius = Math.Max(0, Math.Min(Radius - 5, newInnerRadius));
                    break;
            }
            //调整大小
            if (rect.Width > 3)
            {
                rectBound = rect;
            }
            ExceteMoveCallback(this);
        }
        public override void DrawShapeWithHandle(Graphics graphics)
        {
            Color current = IsSelected ? SelectedColor : BackColor;
            // 1、绘制外轮廓
            using (Pen brush = new Pen(current))
            {
                graphics.DrawEllipse(brush, RectFBound);
            }
            if (IsSelected)
            {
                // 2、计算填充路径区域（外部圆减去内部圆）
                using (GraphicsPath path = new GraphicsPath())
                {
                    path.AddEllipse(RectFBound);    //外轮廓
                    if (InnerRadius > 0)
                    {
                        RectangleF innerRect = new RectangleF(
                            Center.X - InnerRadius, 
                            Center.Y - InnerRadius,
                            InnerRadius * 2, 
                            InnerRadius * 2);
                        path.AddEllipse(innerRect); //内轮廓
                    }
                    using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha, current)))
                    {
                        graphics.FillPath(brush, path);
                    }
                }
                //绘制手柄
                DrawHandles(graphics);
            }
            //绘制形状描述
            DrawDescription(graphics);
            //绘制区域中心
            DrawRegionCenter(graphics);
        }
        public override void DrawHandle(Graphics graphics, int x, int y)
        {
            //1、计算手柄区域
            Rectangle handleRect = new Rectangle( x - HandleSize / 2, y - HandleSize / 2, HandleSize, HandleSize);
            //2、填充区域
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha * 2, HandleColor)))
            {
                graphics.FillRectangle(brush, handleRect);
            }
            //3、绘制区域边缘
            using (Pen pen = new Pen(HandleColor, BorderWidth))
            {
                graphics.DrawRectangle(pen, handleRect);
            }
        }
        public override void DrawHandle(Graphics graphics, float x, float y)
        {
            //1、计算手柄区域
            RectangleF[] handleRect = new RectangleF[] {
                new RectangleF(x - HandleSize / 2, y - HandleSize / 2, HandleSize, HandleSize)};
            //2、填充区域
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha * 2, HandleColor)))
            {
                graphics.FillRectangles(brush, handleRect);
            }
            //3、绘制区域边缘
            using (Pen pen = new Pen(HandleColor, BorderWidth))
            {
                graphics.DrawRectangles(pen, handleRect);
            }
        }
        public override void DrawHandle(Graphics graphics, PointF point)
        {
            RectangleF handleRect = new RectangleF(
                point.X - HandleSize / 2, point.Y - HandleSize / 2,
                HandleSize, HandleSize);
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha * 2, HandleColor)))
            {
                graphics.FillRectangle(brush, handleRect);
            }
            using (Pen pen = new Pen(HandleColor, BorderWidth))
            {
                graphics.DrawRectangles(pen, new RectangleF[] { handleRect });
            }
        }
        public override ShapeHandleType GetHandleType(PointF point)
        {
            // 检查右侧手柄
            Point rightHandle = new Point((int)(Center.X + Radius), (int)Center.Y);
            if (IsInHandle(point, rightHandle))
            {
                return ShapeHandleType.Right;
            }
            // 检查内部手柄
            Point innerHandle = new Point((int)(Center.X + InnerRadius), (int)Center.Y);
            if (IsInHandle(point, innerHandle))
            {
                return ShapeHandleType.Inner;
            }
            return ShapeHandleType.None;
        }
        public override Cursor GetSystemHandleType(PointF point)
        {
            switch (GetHandleType(point))
            {
                case ShapeHandleType.Right:
                case ShapeHandleType.Inner:
                    return Cursors.SizeWE;
                default:
                    return Cursors.SizeAll;
            }
        }
        public override bool IsInRegion(PointF point)
        {
            //手柄不是None必定在区域内，
            return (GetHandleType(point) != ShapeHandleType.None) || IsInBackground(point);
        }
        public override bool IsInBackground(PointF point)
        {
            Point innerHandle = new Point((int)(Center.X + InnerRadius), (int)Center.Y);
            return RectFBound.Contains(point)&& !IsInHandle(point, innerHandle);
        }
        public override bool IsInHandle(PointF inPoint, PointF point)
        {
            int detectionSize = HandleOutSize + 2;
            RectangleF handleRect = new RectangleF(
                point.X - detectionSize / 2, point.Y - detectionSize / 2,
                detectionSize, detectionSize);
            return handleRect.Contains(inPoint);
        }
        public override bool IsInRotateHandle(PointF point)
        {
           return false;
        }

        #endregion
        #region 重写方法：形状变更事件
        public override void ExceteMoveCallback(ShapeBase obj)
        {
            MoveEvents?.Invoke(this, Center);
        }
        public override void ExceteRotateCallback(ShapeBase obj)
        {
            RotateEvents?.Invoke(this, Center);
        }
        public override void ExceteResizeCallback(ShapeBase obj)
        {
            ResizeEvents?.Invoke(this, Center);
        }
        public override void ExceteAttachCallback(ShapeBase obj)
        {
            AttachEvents?.Invoke(this, Center);
        }
        public override void ExceteDetachCallback(ShapeBase obj)
        {
            DetachEvents?.Invoke(this, Center);
        }
        public override void ExceteSelectedCallback(ShapeBase obj)
        {
            SelectedEvents?.Invoke(this, Center);
        }
        #endregion
    }
}
